package de.unikoblenz.west.csxpoi.server;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * A collection of methods for handling HTTP requests.
 */
public class ServletHelper {

	/**
	 * Tests whether the specified request is a collection request (if there is
	 * no parameter named "id").
	 * 
	 * @param request
	 *            the request to test
	 * @return true if the specified request is a collection request
	 */
	public static boolean isCollectionRequest(HttpServletRequest request) {
		return request.getParameter("id") == null;
	}

	/**
	 * Tests whether the specified request is a member request (if there is a
	 * parameter named "id").
	 * 
	 * @param request
	 *            the request to test
	 * @return true if the specified request is a member request
	 */
	public static boolean isMemberRequest(HttpServletRequest request) {
		return request.getParameter("id") != null;
	}

	/**
	 * Resolves the string value of the specified parameter.
	 * 
	 * @param request
	 *            the request containing the parameter
	 * @param parameter
	 *            the name of the parameter
	 * @return the string value of the specified parameter
	 * @throws ServerException
	 */
	public static String resolveStringParameter(HttpServletRequest request,
			String parameter) throws ServerException {
		
		try {
		String value = request.getParameter(parameter);
		if (value == null)
			return "";
		else
			return URLDecoder.decode(value, "UTF-8");
		} catch (UnsupportedEncodingException e) {
			throw new ServerException();
		}
	}

	/**
	 * Resolves the list of string values of parameters based on the specified
	 * base. If the specified parameter is "par", all values of parameters named
	 * "par1", "par2", etc. are resolved.
	 * 
	 * @param request
	 *            the request containing the parameters
	 * @param base
	 *            the base of the name of the parameter
	 * @return a list of string values of the specified parameter base
	 * @throws ServerException
	 */
	public static List<String> resolveStringListParameter(
			HttpServletRequest request, String base) throws ServerException {
		String categoryParameter = null;
		List<String> strings = new ArrayList<String>();
		for (int i = 1; (categoryParameter = request.getParameter(base + i)) != null; i++) {
			try {
				strings.add(URLDecoder.decode(categoryParameter, "UTF-8"));
			} catch (UnsupportedEncodingException e) {
				throw new ServerException();
			}
		}
		return strings;
	}

	/**
	 * Resolves the double value of the specified parameter.
	 * 
	 * @param request
	 *            the request containing the parameter
	 * @param parameter
	 *            the name of the parameter
	 * @return the double value of the specified parameter
	 * @throws ServerException
	 */
	public static double resolveDoubleParameter(HttpServletRequest request,
			String parameter) throws ServerException {
		String value = request.getParameter(parameter);
		if (value == null)
			throw new ServerException();
		try {
			return Double.valueOf(value);
		} catch (NumberFormatException e) {
			throw new ServerException();
		}
	}

	/**
	 * Disables caching for the specified response.
	 * 
	 * @param response
	 *            the response for which to disable caching
	 */
	public static void disableCaching(HttpServletResponse response) {

		// From http://onjava.com/pub/a/onjava/excerpt/jebp_3/index2.html

		response.setHeader("Expires", "Sat, 6 May 1995 12:00:00 GMT");
		response.setHeader("Cache-Control",
				"no-store, no-cache, must-revalidate");
		response.addHeader("Cache-Control", "post-check=0, pre-check=0");
		response.setHeader("Pragma", "no-cache");
	}

	/**
	 * Creates a writer supporting UTF-8.
	 * 
	 * @param response
	 *            the response for which to get the writer
	 * @return a writer supporting UTF-8
	 */
	public static PrintWriter utf8Writer(HttpServletResponse response) {
		try {
			return new PrintWriter(new OutputStreamWriter(response
					.getOutputStream(), "UTF8"), true);
		} catch (UnsupportedEncodingException e) {
			return null;
		} catch (IOException e) {
			return null;
		}
	}

	/**
	 * filters escape symbols like &,<, >, out of a string
	 * 
	 * @param input
	 *            the unfiltered String
	 * @return the filtered String
	 */
	  public static String filterSymbols(String input){
		    final StringBuilder result = new StringBuilder();
		    final StringCharacterIterator iterator = new StringCharacterIterator(input);
		    char character =  iterator.current();
		    while (character != CharacterIterator.DONE ){
		      if (character == '<') {
		        result.append("&lt;");
		      }
		      else if (character == '>') {
		        result.append("&gt;");
		      }
		      else if (character == '\"') {
		        result.append("&quot;");
		      }
		      else if (character == '\'') {
		        result.append("&#039;");
		      }
		      else if (character == '&') {
		         result.append("&amp;");
		      }
		      else {		        
		        result.append(character);
		      }
		      character = iterator.next();
		    }
		    return result.toString();
		  }
}
